package rpt.task;


import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Vector;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.URLEncoder;
import java.net.UnknownHostException;



import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.log4j.Logger;

import rpt.web.WebController;

class CLocker{
	private int counter=0;
	private int coutsucc=0;
	private int coutfail=0;
	
	public void addfail(){
		coutfail++;
	}
	public void delfail(){
		coutfail--;
	}
	public int getfail(){
		return coutfail;
	}
	public void addsucc(){
		coutsucc++;
	}
	public void delsucc(){
		coutsucc--;
	}
	public int getsucc(){
		return coutsucc;
	}
	
	public void add(){
		counter++;
	}
	public void del(){
		counter--;
	}
	public int getcounter(){
		return counter;
	}
	public boolean iszero(){
		return counter==0;
	}
}
public class TerminalMgt{
	static int sn = 0;
	static Logger log = Logger.getLogger(TerminalMgt.class);
	static final boolean MD5CHECK = true;
	static final boolean IPCHECK = true;
	public static String ContentServerAddr;
	public static String TerminalServerAddr;
	static final int  RETRY_COUNT  = 0;
	//static  int counter;   
	private static final long serialVersionUID = 1L;
	static char FSP = '/';
	static private SimpleDateFormat fmt = new SimpleDateFormat(
			FSP+"yyyy"+FSP
			+"MM"+FSP+"dd"+FSP+
			"HH-mm-ss");
	static private SimpleDateFormat sfmt = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
	static String TAGSTART ="<!--notice_start-->";
	static String TAGEND ="<!--notice_end-->";
	final static int terminalPort= 8090;
	static String iPAddrs = getLocalIP();
	
	private String[] ipaddrs;
	private String cmd;
	private String output;
	private Date dt_last;
	private String ipstr;
	private int id;
	
	public String[] getIpaddrs() {
		return ipaddrs;
	}
	public void setIpaddrs(String[] ipaddrs) {
		this.ipaddrs = ipaddrs;
		StringBuilder builder = new StringBuilder();
		for(String s : ipaddrs) {
		    builder.append(s+",");
		}
		ipstr =  builder.toString();
	}
	public String getCmd() {
		return cmd;
	}
	public void setCmd(String cmd) {
		this.cmd = cmd;
	}
	public TerminalMgt(){
		sn++;
		this.id = sn;
		this.init();
		WebController.putTask("task"+this.id, this);
	}
	public String printHTML(){
		return "<table><tr><th>状态项</th><th>状态值</th></tr>"
				+"<tr><td>序号</td><td>"+id+"</td></tr>"
				+"<tr><td>命令</td><td>"+cmd+"</td></tr>"
				+"<tr><td>终端地址</td><td>"+(ipstr==null?"":ipstr)+"</td></tr>"
				+"<tr><td>最近更新</td><td>"+(dt_last==null?"":sfmt.format(dt_last))+"</td></tr>"
				+"<tr><td>最近状态</td><td>"+(output==null?"":output)+"</td></tr></table>";
	}
	public String getOutput(){
		return this.output;
	}
	public static String getLocalIP(){
		StringBuffer sbuf = new StringBuffer();
		try{
		Enumeration e1 = (Enumeration) NetworkInterface.getNetworkInterfaces();
		while(e1.hasMoreElements()){
			NetworkInterface ni = (NetworkInterface) e1.nextElement();
			Enumeration e2 = ni.getInetAddresses();
			while(e2.hasMoreElements()){
				InetAddress ia = (InetAddress) e2.nextElement();
				if (ia instanceof Inet6Address) continue; //omit IPv6 address
				sbuf.append(ia.getHostAddress());
				if(e2.hasMoreElements())
					sbuf.append(",");
			}
			if(e1.hasMoreElements())
				sbuf.append(";");
		}
		}catch(Exception e){
			e.printStackTrace();
		}
		return sbuf.toString();
	}
	public void init()  {
		try {
			TerminalServerAddr = InetAddress.getLocalHost().getHostAddress();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if(ContentServerAddr==null)
			ContentServerAddr = TerminalServerAddr;
	}
	//c4w 9.17
	 public synchronized String sendCmd() throws UnsupportedEncodingException, InterruptedException {
		if(ipaddrs==null || cmd == null)
			return "无效任务";
		Vector tl = new Vector();
		CLocker cl = new CLocker();
		log.info("send command:"+cmd);
		for(int i=0; i<ipaddrs.length; i++){
			String ipstr = ipaddrs[i].trim();
			log.info(ipstr);
			HttpClientParams params = new HttpClientParams();
			params.setParameter(HttpMethodParams.RETRY_HANDLER,
                          new DefaultHttpMethodRetryHandler(RETRY_COUNT,true));
	        HttpClient httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());
	        httpClient.getHostConfiguration().setHost(ipstr, terminalPort, "http");
	        httpClient.setParams(params);
	        String surl = cmd;
	        //系统时间
	        surl+=URLEncoder.encode("&stime="+sfmt.format(new Date()),"utf-8");
	        if(IPCHECK)
	        	surl+="&ip="+iPAddrs;
	        if(MD5CHECK)
	        	surl = surl +Encrypt.MD5Encode(surl);
			GetMethod get = new GetMethod(surl);	//exec?cmd=setparam%26terminal_page%3Dhttp%3A%2F%2Flocalhost%3A8090%2Fsettings.html%26device_type%3D4%26notify_height%3D32%26notify_pos%3D0%26notify_trans%3D255%26server_port%3D8090%26terminal_idlespan%3D60%26terminal_shutdowntm%3D16%3A30%3A00%26stime%3D08%2F26%2F2008+15%3A56%3A54&ip=127.0.0.1;192.168.0.20965925abe0a19c5d2f9ffb61e0c617255	
            get.setFollowRedirects(true);
            GetThread th = new GetThread(httpClient, get, i + 1,cl,ipstr);
            tl.add(th);
		}
		for(int i=0;i<tl.size(); i++){
			GetThread th = (GetThread)tl.get(i);
			th.start();
		}
		if(tl.size()>0){
			synchronized(cl){ 
				cl.wait();
			}
		}
        StringBuffer fbuf = new StringBuffer();
        StringBuffer cbuf = new StringBuffer();
        for(int i=0; i<tl.size(); i++){
        	GetThread th =(GetThread)tl.get(i);
        	if(th.bsucc){
        		cl.addsucc();
        		String tc = th.getTcfg();
        		cbuf.append(tc+"\n");
        	}
        	else{
        		cl.addfail();
        		String tc = th.getTcfg();
        		fbuf.append(tc+"\n");
        	}
        }
        StringBuffer sbuf = new StringBuffer();
        if(cl.getsucc()>0)
          sbuf.append(cl.getsucc()+"个终端应答成功\n");
          sbuf.append(cbuf);
        if(cl.getfail()>0){
          sbuf.append("以下"+cl.getfail()+"个终端连接失败:\n");
          sbuf.append(fbuf);
        } 
        if(cl.getsucc()==0 && cl.getfail()==0){
        	sbuf.append("无激活状态终端");
        }
        String out = sbuf.toString();
        this.dt_last=new Date();
        this.output = out;
        log.info(out);
        log.info("Memory free:"+
				Runtime.getRuntime().freeMemory()+",total:"
				+Runtime.getRuntime().totalMemory()+",max:"
				+Runtime.getRuntime().maxMemory());
        return out;
	}
 	
	/**
	 * @param args
	 * @throws InterruptedException 
	 */
	public static void main(String[] args) throws InterruptedException {
	}

	
    /**
     * A thread that performs a GET.
	 */
    static class GetThread extends Thread {
        public String getTcfg() {
			return tcfg;
		}

		public void setTcfg(String tcfg) {
			this.tcfg = tcfg;
		}
		private boolean bsucc;
        private HttpClient httpClient;
        private GetMethod method;
        private int id;
        private CLocker locker;
        private String tcfg;
        
        public GetThread(HttpClient httpClient, GetMethod method, int id,CLocker locker,String tcfg) {
            this.httpClient = httpClient;
            this.method = method;
            this.id = id;
            this.locker = locker;
            this.tcfg = tcfg;
            synchronized(locker){
            	locker.add();
            	System.out.println("counter++ locker: "+locker+"    counter:"+locker.getcounter());
            }
        }
        
        public boolean getBsucc(){
        	return bsucc;
        }
        /**
         * Executes the GetMethod and prints some satus information.
         */
        public void run() {            
            try {                
                // execute the method
                httpClient.executeMethod(method);
                // get the response body as an array of bytes
                byte[] bytes = method.getResponseBody();   
                bsucc = true;
                //System.out.println(id + " - " + bytes.length + " bytes read");                
            } catch (Exception e) {
               // System.out.println(id + " - error: " + e);
                bsucc = false;
            } finally {
                // always release the connection after we're done 
                method.releaseConnection();
                synchronized(locker) {
                	locker.del();
                	//System.out.println("counter-- locker: "+locker+"    counter:"+locker.getcounter());
                    if(locker.iszero())
                        locker.notify();
                }
            }
        }
       
    }
}
